<!doctype html>
<html lang="en">
	<head>
		<title>3D Product configurator</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<style>
			body {
				font-family: Monospace;
				background-color: #f0f0f0;
				margin: 0px;
				overflow: hidden;
			}
		</style>
		<script src="js/webglhelper.js" type="text/javascript"></script>
		<script src="js/require.js" type="text/javascript"></script>

		<script type="text/javascript">
		    
			var container;
			var camera, controls, scene, projector, renderer;
			var sprite1, canvas1, context1;
			var objects = [], pickableObjects = [], plane;

			var mouse,// = new THREE.Vector2(),
			offset,// = new THREE.Vector3(),
			INTERSECTED, SELECTED;

			function start() {
			    require(["js/three.min.js"], function () {
			    	require(["js/TrackballControls.js"], function () {
				        init();
				        animate();
				        
				        // load environment
				        addStage();
				        
				        // load rack
				        addRack();
				        
				        addParts(100,0x000000);
				        addParts(200,0xff0000);
				        addParts(300,0x00ff00);
				        addParts(400,0x0000ff);

				        addSprite();
				        
				        // load pickableObjects
				        
				        //addParts('models/servercomponent1.dae', 2, true);
						//addParts('models/servercomponent1.dae', 3, true);
						//addParts('models/servercomponent1.dae', 4, true);
						//addParts('models/servercomponent2.dae', 8, true);
						//addParts('models/servercomponent3.dae', 9, true);
				    });
			    });
			}

			function addSprite(){
				// create a canvas element
				canvas1 = document.createElement('canvas');
				context1 = canvas1.getContext('2d');
				context1.font = "Bold 20px Arial";
				context1.fillStyle = "rgba(0,0,0,0.95)";
			    context1.fillText('Hello, world!', 0, 20);
			    
				// canvas contents will be used for a texture
				texture1 = new THREE.Texture(canvas1) 
				texture1.needsUpdate = true;
				
				////////////////////////////////////////
				
				sprite1 = new THREE.Sprite( { map: texture1, useScreenCoordinates: true, alignment: THREE.SpriteAlignment.topLeft } );
				sprite1.position.set( 50, 50, 0 );
				scene.add( sprite1 );	

				//////////////////////////////////////////
			}
			
			function addStage(){
				var stage = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000, 10, 10 ), new THREE.MeshBasicMaterial( { color: 0xc8c8c8, opacity: 0.8, transparent: false, wireframe: false } ) );
				stage.geometry.applyMatrix( new THREE.Matrix4().makeRotationX( -Math.PI / 2 ) );
				stage.visible = true;
				stage.position.y=-700;
				stage.receiveShadow = true;
				scene.add( stage );
			}


			function addRack(){
				//bottom
				var object = new THREE.Mesh( 
									new THREE.CubeGeometry( 615, 15, 800 ), 
									new THREE.MeshLambertMaterial( { color: 0xc8c8c8 } ) 
								);
				object.material.ambient = object.material.color;
				object.position.x = 0;
				object.position.y = -700;
				object.position.z = 0;
				//object.castShadow = true;
				object.receiveShadow = true;
				scene.add( object );
				
				//top
				object = new THREE.Mesh( 
									new THREE.CubeGeometry( 615, 15, 800 ), 
									new THREE.MeshLambertMaterial( { color: 0xc8c8c8 } ) 
								);
				object.material.ambient = object.material.color;
				object.position.x = 0;
				object.position.y = 700;
				object.position.z = 0;
				object.castShadow = true;
				object.receiveShadow = true;
				scene.add( object );

				//left
				object = new THREE.Mesh( 
						new THREE.CubeGeometry( 15, 1400, 800 ), 
						new THREE.MeshLambertMaterial( { color: 0xc8c8c8 } ) 
					);
				object.material.ambient = object.material.color;
				object.position.x = -300;
				object.position.y = 0;
				object.position.z = 0;
				object.castShadow = true;
				object.receiveShadow = true;
				scene.add( object );
				
				//right
				object = new THREE.Mesh( 
						new THREE.CubeGeometry( 15, 1400, 800 ), 
						new THREE.MeshLambertMaterial( { color: 0xc8c8c8 } ) 
					);
				object.material.ambient = object.material.color;
				object.position.x = 300;
				object.position.y = 0;
				object.position.z = 0;
				object.castShadow = true;
				object.receiveShadow = true;
				scene.add( object );
				
				//back
				object = new THREE.Mesh( 
						new THREE.CubeGeometry( 600, 1400, 15 ), 
						new THREE.MeshLambertMaterial( { color: 0xc8c8c8 } ) 
					);
				object.material.ambient = object.material.color;
				object.position.x = 0;
				object.position.y = 0;
				object.position.z = -400;
				object.castShadow = true;
				object.receiveShadow = true;
				scene.add( object );				
			}

			
			function addParts(y,colorHex){
				var geometry = new THREE.CubeGeometry( 550, 80, 700 );

				var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: colorHex } ) );
				object.material.ambient = object.material.color;

				object.position.x = 0;
				object.position.y = y;
				object.position.z = 0;

				object.castShadow = true;
				object.receiveShadow = true;
				object.name="TEST";

				scene.add( object );
				
				pickableObjects.push ( object );								
			}
			
			
			
			
			function init() {
			    mouse = new THREE.Vector2();
			    offset = new THREE.Vector3();

			    container = document.getElementById('container');
				scene = new THREE.Scene();

				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
				camera.name = 'Camera';
				camera.position.x = 200;
				camera.position.z = 1500;
				camera.position.y = 0;

				scene.add( camera );

				
				controls = new THREE.TrackballControls( camera );
				controls.rotateSpeed = 1.0;
				controls.zoomSpeed = 1.2;
				controls.panSpeed = 0.8;
				controls.noZoom = true;
				controls.noPan = true;
				controls.staticMoving = true;
				controls.dynamicDampingFactor = 0.3;
				
				
				scene.add( new THREE.AmbientLight( 0x505050 ) );

				var light = new THREE.SpotLight( 0xffffff, 1.5 );
				light.position.set( 500, 800, 800 );
				light.castShadow = true;

				light.shadowCameraNear = 200;
				light.shadowCameraFar = camera.far;
				light.shadowCameraFov = 100;

				light.shadowBias = -0.00022;
				light.shadowDarkness = 0.25;

				light.shadowMapWidth = 1024;
				light.shadowMapHeight = 1024;
				
				//light.shadowCameraVisible = true;

				scene.add( light );
				
				light = new THREE.PointLight(0x505050);
				light.position.set(0,700,1000);
				scene.add( light )


				plane = new THREE.Mesh( new THREE.PlaneGeometry( 3000, 3000, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0x000000, opacity: 0.25, transparent: true, wireframe: true } ) );
				plane.visible = false;
				scene.add( plane );

				projector = new THREE.Projector();

				// renderer
				var externalCanvas = document.getElementById('renderCanvas');
				renderer = new THREE.WebGLRenderer({ 'canvas': externalCanvas, 'antialias': true });
				renderer.sortObjects = false;
				renderer.setSize( window.innerWidth, window.innerHeight );
				renderer.shadowMapEnabled = true;
				renderer.shadowMapSoft = true;

				//var info = document.createElement( 'div' );
				//info.style.position = 'absolute';
				//info.style.top = '10px';
				//info.style.width = '100%';
				//info.style.textAlign = 'center';
				//info.innerHTML = '<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> webgl - draggable cubes';
				//container.appendChild( info );

				//stats = new Stats();
				//stats.domElement.style.position = 'absolute';
				//stats.domElement.style.top = '0px';
				//container.appendChild( stats.domElement );

				renderer.domElement.addEventListener( 'mousemove', onDocumentMouseMove, false );
				renderer.domElement.addEventListener( 'mousedown', onDocumentMouseDown, false );
				renderer.domElement.addEventListener( 'mouseup', onDocumentMouseUp, false );
				
				window.addEventListener('resize', onWindowResize, false);

			}

			function myFloor(n) {
				  return Math.floor(n / 100) * 100; // return 100 if number is between 100~199, 200 if 200~299.
			}
			
			function onDocumentMouseMove( event ) {

				event.preventDefault();

				mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
				mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

				var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
				projector.unprojectVector( vector, camera );

				// update sprite position
				sprite1.position.set( event.clientX, event.clientY, 0 );
				
				var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );

				if ( SELECTED ) {

					var intersects = ray.intersectObject( plane );
					//if (intersects[ 0 ]) SELECTED.position.copy( intersects[ 0 ].point.subSelf( offset ) ); // copy the y position.
					if (intersects[ 0 ]){ 
						SELECTED.position.y = intersects[ 0 ].point.subSelf( offset ).y;  // limit the movement to only y-axis
						SELECTED.position.y = myFloor(SELECTED.position.y);						
					}
					return;
				}

				var intersects = ray.intersectObjects( pickableObjects );

				if ( intersects.length > 0 ) {

					if ( INTERSECTED != intersects[ 0 ].object ) {

						if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );

						INTERSECTED = intersects[ 0 ].object;
						INTERSECTED.currentHex = INTERSECTED.material.color.getHex();

						plane.position.copy( INTERSECTED.position );
						plane.lookAt( camera.position );
					}

					container.style.cursor = 'pointer';
				} else {
					if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
					INTERSECTED = null;

					container.style.cursor = 'auto';
				}
			}

			function onDocumentMouseDown( event ) {

				event.preventDefault();

				var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
				projector.unprojectVector( vector, camera );

				var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );

				var intersects = ray.intersectObjects( pickableObjects ); //change this to pickableObjects.

				if ( intersects.length > 0 ) {

					controls.enabled = false;

					SELECTED = intersects[ 0 ].object;
					
					SELECTED.position.z = 200;  // slide the rack out little bit

					// update the plane's up vector toward the camera, for accurate picking.
					plane.position.copy( INTERSECTED.position );
					plane.lookAt( camera.position );
					
					var intersects = ray.intersectObject( plane );
					if(intersects[ 0 ]) offset.copy( intersects[ 0 ].point ).subSelf( plane.position );

					container.style.cursor = 'move';
					
					
					// SPRITE TEST
					// create a canvas element
					canvas1 = document.createElement('canvas');
					context1 = canvas1.getContext('2d');
					context1.font = "Bold 20px Arial";
					context1.fillStyle = "rgba(0,0,0,0.95)";
				    context1.fillText('Hello, world!', 0, 20);
				    
					// canvas contents will be used for a texture
					texture1 = new THREE.Texture(canvas1) 
					texture1.needsUpdate = true;
					
					////////////////////////////////////////
					
					sprite1 = new THREE.Sprite( { map: texture1, useScreenCoordinates: true, alignment: THREE.SpriteAlignment.topLeft } );
					sprite1.position.set( 50, 50, 0 );
					scene.add( sprite1 );	

					//////////////////////////////////////////
					
					// update text, if it has a "name" field.
					if ( intersects[ 0 ].object.name )
					{
					    context1.clearRect(0,0,640,480);
						var message = intersects[ 0 ].object.name;
						var metrics = context1.measureText(message);
						var width = metrics.width;
						context1.fillStyle = "rgba(0,0,0,0.95)"; // black border
						context1.fillRect( 0,0, width+8,20+8);
						context1.fillStyle = "rgba(255,255,255,0.95)"; // white filler
						context1.fillRect( 2,2, width+4,20+4 );
						context1.fillStyle = "rgba(0,0,0,1)"; // text color
						context1.fillText( message, 4,20 );
						
						texture1.needsUpdate = true;
					}
					else
					{
						context1.clearRect(0,0,300,300);
						texture1.needsUpdate = true;
					}
					
					
				}
			}

			function onDocumentMouseUp( event ) {
				event.preventDefault();
				controls.enabled = true;

				if ( INTERSECTED ) {
					//plane.position.copy( INTERSECTED.position );

					SELECTED.position.z = 0;  // put it back
					SELECTED = null;
				}
				
				context1.clearRect(0,0,300,300);
				texture1.needsUpdate = true;

				container.style.cursor = 'auto';
			}
			
			function onWindowResize() {
			    camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();

				renderer.setSize(window.innerWidth,window.innerHeight);
				render();
			}

			function animate() {
				requestAnimationFrame( animate );
				render();
			}

			function render() {
				controls.update();
				renderer.render( scene, camera );
			}

		</script>		
	</head>
	<body>
        <!-- create container and canvas using markup -->
        <div id="container">
            <!-- create proper element (native canvas element or IEWebGL plugin object element) depending on web browser and WebGL support -->
            <script id="WebGLCanvasCreationScript" type="text/javascript">                
            	WebGLHelper.CreateGLCanvasInline('renderCanvas', start)
            </script>
        </div>
	</body>
</html>



